C++ Core Guidelines の紹介
https://youtu.be/KMpHV4Z740Y
質問・コメント
あまり自明でないもの(言われないと見落としてしまうようなこと)、知りたいです Reputeless.icon
Core Guidelines って、最近でもメンテ・追加されてるんですか? (どこかで更新の差分を確認できますか?)Reputeless.icon
コミット履歴を見ると活発に更新されていることが分かります。改訂の履歴を説明した文書はあるかどうかわかりません(多分ない)tetsurom.icon Guidelines の番号は一貫してる? 途中で変わったりする? Reputeless.icon
多分変えない。静的解析でガイドラインのチェックをするツールなどもあり、ルール番号が出たりするのと、ガイドラインの個別URLが壊れるため tetsurom.icon
オーバーロードよりもデフォルト引数を優先するのは意外でした。標準ライブラリもどんどんオーバーロードに移行しているのですが… 。たとえばコンテナのvector(Allocator alloc = Allocator());のようなコンストラクタはexplicitをつけるのがむずかしいこともあり、vector();とexplicit vector(Allocator alloc);に分割されています。この指針の理由として「オーバーロードが同じ意味論で実装される保証はない。デフォルト引数によってコードのコピペを避けられる」というのが挙げられていますね (cpp_akira) デフォルト引数は数が増えてくると管理がむずかしくなるのもあり、オーバーロードの方が望ましいケースは多い気がします。f(T1 a, T2 b = T2{}, T3 c = T3{}); これにaとcだけ指定したい場合にbのデフォルト引数をユーザーコードが管理するよりはAPI提供者が管理したほうが管理しやすいと思います (cpp_akira)
「選べる場合は」というのが結構あいまいな基準で、explicitを付けるためとか、APIとしてわかりやすいという場合は、オーバーロードでもいいんじゃないかという気がしますtetsurom.icon
引数が多い関数は引数のための構造体を指示付き初期化するのが今後はいいかもしれないですね tetsurom.icon
I.13 / R.14, サイズ固定の配列ならこういう渡し方を書いたりするときもあります Reputeless.icon code:cpp
# include <iostream>
void F(const float(&color)4) {
std::cout << color0 << ", " << color1 << ", " << color2 << ", " << color3 << '\n'; }
int main()
{
const float color4 = { 0.1f, 0.2f, 0.3f, 0.4f }; F(color);
}
これも固定長 span にできますね ( void F(std::span<float, 4> color); )
span が無い環境 (C++20 より昔) だとこれ使ったりする Reputeless.icon
GSLでも span を提供しています (昔は string_view もあった) tetsurom.icon
F.15の「コストが小さい」ってレジスタに乗り切るかどうかってニュアンスですかね?zbdk.icon そんな気はしますが明記されてないようです tetsurom.icon
「コストが中程度」でも出力の場合は値返しが推奨されるんですね。変数サイズが1KBもあったら参照引数経由で返してしまいそう…zbdk.icon
F.20 を見ると、オブジェクトが大きい場合は unique_ptrで返すことも推奨しています。F.15の表の誤植でその事が抜けてしまっているようです。 値渡しにするときの閾値の一般論はポインタ2つ分(16byte)が目安だと思ってました。キャッシュに載ってる前提なら確かにもう少し大きくても良いのかもですね。onihusube.icon
そもそも16byteという基準もどこから出て来たのか・・・?onihusube.icon
F.16 "What is “cheap to copy” depends on the machine architecture, but two or three words (doubles, pointers, references) are usually best passed by value." らしいです (そうなのか……) tetsurom.icon こういうのが出てました、ビャーネ先生作 onihusube.icon
7 月の標準化委員会 paper ですね。要約するとどういうことだろう Reputeless.icon
C++ Core Guildlines タイトル日本語訳、めっちゃ良い資料なので、共同で本格的に整備したいですね Reputeless.icon
確かに日本語訳助かりました!zbdk.icon
共同で翻訳する場合、本家の更新をうまく拾えるシステムが欲しい (by tetsurom.icon)
巷ではinlineはインライン展開に意味ないというのが定説ですけど、小さい関数にはinlineつけよう!っていうのがあって、中々自明ではなかった記憶(個人的に onihusube.icon "Specifying inline encourages the compiler to do a better job." とあるので、"意味ない"というのは実装の都合という立場なのかも…… tetsurom.icon
unique_ptr<T[]> はあまり推奨されないんでしょうか?mmYYmmdd.icon
P.6 などを見るに推奨されない雰囲気ですね。サイズ情報が失われてしまうため。yohhoy.icon Herb Sutterさんが関数引数について少し前にこんなポストしてました onihusube.icon
Windowsのx64呼び出し規約だと、1レジスタに収まらない引数はスタック上のポインタ渡しになります onihusube.icon
これのせいで、MSVCのspanが厳密に値渡しにならないとか・・・
spanを受け取るルールは、C++23でout_ptrとinout_ptrが入ることでちょっと複雑になりそうな感じがしますね。advancedなツールだと思いますが (cpp_akira)
P1132R7これは便利ですね。CComPtr とか、operator & ()でこの動作をするのでとてもわかりにくい…… tetsurom.icon F.15のmove cheapな場合はf(const X&)+f(X&&)を両方書けということみたいですが、f(X)でやってますね。引数が多くなると組み合わせが爆発してしまうのも厳しいなと思いますがtemplateで書けば問題ない?gassa.icon
両方書くのは "Advanced parameter passing" となっていて、必要な時だけでよいとなっています。実際ほとんど f(X) にしていますね…… tetsurom.icon